﻿using huqiang.Framework.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;

/// <summary>
/// 版本控制
/// </summary>
public class AssetsVersionControl
{
    public const string sec_Public = "Public";
    public const string sec_Assets = "Assets";
    public const string sec_Lua = "Lua";
    public const string sec_Other = "Other";
    public const string sec_MP4 = "mp4";
    const string pub_AssetsVersion = "assversion";
    const string pub_AppVersion = "appversion";
    const string pub_AppSize = "appsize";
    
    public static AssetsSetting AssetsRecord;
    public static AssetsSetting BuildInVersion;
    public static AssetsSetting NetVersion;
#if DEBUG
    public static List<string> abUseRecords;
    static void AddRecord(string bundleName)
    {
        if (abUseRecords == null)
            abUseRecords = new List<string>();
        if (abUseRecords.Contains(bundleName))
            return;
        abUseRecords.Add(bundleName);
    }
    public static void WriteRecord()
    {
        if(abUseRecords!=null)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < abUseRecords.Count; i++)
            {
                if (i > 0)
                    sb.Append('\n');
                sb.Append(abUseRecords[i]);
            }
            string rp = LocalSetting.persistentDataPath + "/abbuse.txt";
            if (File.Exists(rp))
                File.Delete(rp);
            File.WriteAllText(rp, sb.ToString());
        }
    }
    public static string GetRecord()
    {
        if (abUseRecords != null)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < abUseRecords.Count; i++)
            {
                if (i > 0)
                    sb.Append(',');
                sb.Append(abUseRecords[i]);
            }
            return sb.ToString();
        }
        return "";
    }
    public static string GetRecord(ref int index)
    {
        if (abUseRecords != null)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = index; i < abUseRecords.Count; i++)
            {
                if (i > 0)
                    sb.Append(',');
                sb.Append(abUseRecords[i]);
            }
            index = abUseRecords.Count;
            return sb.ToString();
        }
        return "";
    }
#endif
    /// <summary>
    /// 随app打包的资源版本号
    /// </summary>
    public static string buildInAssVersion;
    /// <summary>
    /// 加载内置版本信息
    /// </summary>
    public static void LoadBuildInAssetsVersion()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        byte[] dat = PlatformTool.Instance.ReadFile(LocalSetting.platform + "/assets.ini");
        BuildInVersion = new AssetsSetting("buildin",dat);
#else
        string filepath = Application.streamingAssetsPath;
        filepath = filepath + "/" + LocalSetting.platform + "/assets.ini";
        BuildInVersion = new AssetsSetting("buildin", filepath);
#endif
        buildInAssVersion = BuildInVersion.GetString(sec_Public, pub_AssetsVersion);
    }
    /// <summary>
    /// 加载已记录的版本信息
    /// </summary>
    public static void LoadRecordVersion()
    {
        string filepath = Application.persistentDataPath;
        filepath = filepath + "/" + LocalSetting.platform + "assets.ini";
        AssetsRecord = new AssetsSetting("record", filepath);
        //HttpDownloader.assetsSetting = AssetsRecord;
    }
    /// <summary>
    /// 加载网络版本信息
    /// </summary>
    /// <param name="path">已下载的文件路径</param>
    public static AssetsSetting LoadNetVersion(string path)
    {
        NetVersion = new AssetsSetting("netassets", path);
        return NetVersion;
    }
    /// <summary>
    /// 获取需要更新的默认资源
    /// </summary>
    /// <param name="values"></param>
    public static void GetAbbNewAssets(List<KeyValue> values, string secName)
    {
        if (NetVersion == null)
            return;
        var net = NetVersion.ini.FindSection(secName);
        if (net == null)
            return;
        INISection buildin = null;
        //INISection record = null;
        if (BuildInVersion != null)
            buildin = BuildInVersion.ini.FindSection(secName);
        if (buildin == null)
        {
            values.AddRange(net.Values);
        }
        else
        {
            for (int i = 0; i < net.Values.Count; i++)
            {
                var kv = net.Values[i];
                var v = buildin.GetValue(kv.key);
                if (v != kv.value)
                    values.Add(kv);
            }
        }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="v0"></param>
    /// <param name="v1"></param>
    /// <returns>小于:-1,相等:0,大于:1</returns>
    public static int CompareNumber(string v0, string v1)
    {
        if (v0 == null)
            return -1;
        if (v1 == null)
            return 1;
        if (v0 == v1)
            return 0;
        string[] ss0 = v0.Split('.');
        string[] ss1 = v1.Split('.');
        if (ss0.Length == ss1.Length)
        {
            for (int i = 0; i < ss0.Length; i++)
            {
                int a = 0;
                int b = 0;
                int.TryParse(ss0[i], out a);
                int.TryParse(ss1[i], out b);
                if (a > b)
                    return 1;
                else if (a < b)
                    return -1;
            }
            return 0;
        }
        if (ss0.Length > ss1.Length)
            return 1;
        return -1;
    }
    public static bool CompareVersion2(string netStr, string curStr, string oriStr)
    {
        if (CompareNumber(netStr, curStr) > -1)
            if (CompareNumber(netStr, oriStr) > -1)
                return true;
        return false;
    }
    static bool CompareString(string v0, string v1)
    {
        if (v0 == null)
            return false;
        if (v1 == null)
            return true;
        long ct = 0;
        string[] sp = v0.Split('_');
        if (sp.Length > 1)
        {
            long.TryParse(sp[1].Split(';')[0], out ct);
        }
        long ot = -1;
        sp = v1.Split('_');
        if (sp.Length > 1)
        {
            long.TryParse(sp[1].Split(';')[0], out ot);
        }
        if (ct > ot)
            return true;
        return false;
    }
    /// <summary>
    /// 当网络版本大于当前版本时返回真
    /// </summary>
    /// <param name="netStr">从网络拉取的版本号</param>
    /// <param name="curStr">当前版本号</param>
    /// <param name="oriStr">apk包中自带的版本号</param>
    public static bool CompareVersion(string netStr, string curStr, string oriStr)
    {
        if (CompareString(netStr, curStr))
            if (CompareString(netStr, oriStr))
                return true;
        return false;
    }
    /// <summary>
    /// 获取最新的资源路径
    /// </summary>
    /// <param name="bundleName"></param>
    /// <returns></returns>
    public static string GetAssetsPath(string bundleName)
    {
        bundleName = bundleName.ToLower();
#if DEBUG
        AddRecord(bundleName);
#endif
        int e = bundleName.LastIndexOf('/');
        if (e < 0)
        {
            return GetNewVersionPath("Assets", bundleName, true);
        }
        else
        {
            string sec = bundleName.Substring(0, e);
            e++;
            string name = bundleName.Substring(e, bundleName.Length - e);
            return GetNewVersionPath(sec, name, false);
        }
    }
    /// <summary>
    /// 获取最新的资源路径
    /// </summary>
    /// <param name="sec"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    public static string GetNewVersionPath(string sec, string key, bool root)
    {
        if (NetVersion != null)
        {  
            string value = NetVersion.GetString(sec, key);
            if (value != null)
            {
                string name = value.Split(';')[0];
                string path;
                if (root)
                 path = LocalSetting.persistentDataPath + "/" + LocalSetting.platform + "/" + name; 
                else path = LocalSetting.persistentDataPath + "/" + LocalSetting.platform + "/" + sec + "/" + name;
                if (File.Exists(path))
                    return path;
            }
        }
        if(BuildInVersion!=null)
        {
            string value = BuildInVersion.GetString(sec, key);
            if (value != null)
            {
                //string name = value.Split(';')[0];
                string path;
                if (root)
                    path = LocalSetting.streamPath + "/" + LocalSetting.platform + "/" + key; 
                else path = LocalSetting.streamPath + "/" + LocalSetting.platform + "/" + sec + "/" + key;
                return path;
            }
        }
#if DEBUG
        if(!LocalSetting.IsEditor)
        {
            if (root)
                Debug.LogError("未能找到资源:" + key);
            else Debug.LogError("未能找到资源:" + sec + "/" + key);
        }
#endif
        return "";
    }
    /// <summary>
    /// 验证程序版本，相同则返回true
    /// </summary>
    /// <returns></returns>
    public static bool CheckAppVersion()
    {
        if(NetVersion!=null)
        {
            string appversion = NetVersion.GetString(sec_Public, pub_AppVersion);
            if (Application.version == appversion)
                return true;
        }
        return false;
    }
    public static string GetAppVersion()
    {
        if (NetVersion != null)
        {
           return NetVersion.GetString(sec_Public, pub_AppVersion);
        }
        return null;
    }
    public static int GetAppSize()
    {
        if (NetVersion != null)
        {
            return NetVersion.GetInt(sec_Public, pub_AppSize);
        }
        return 0;
    }
    /// <summary>
    /// 检测丢失的文件
    /// </summary>
    /// <param name="kvs"></param>
    public static void FileCheck(List<KeyValue> kvs)
    {
        if (NetVersion == null)
            return;
        var net = NetVersion.ini;
        INIReader buildIn = null;
        if (BuildInVersion != null)
            buildIn = BuildInVersion.ini;
        string folder = LocalSetting.AssetsPath + "/";
        var sec = net.FindSection(sec_Assets);
        if (sec != null)
        {
            INISection bi = null;
            if (buildIn != null)
            {
                bi = buildIn.FindSection(sec_Assets);
            }
            var values = sec.Values;
            if (bi == null)
            {
                for (int i = 0; i < values.Count; i++)
                {
                    var key = values[i].key;
                    string path = folder + key;
                    if (!File.Exists(path))
                    {
                        kvs.Add(values[i]);
                    }
                }
            }
            else
            {
                for (int i = 0; i < values.Count; i++)
                {
                    var key = values[i].key;
                    if (bi.GetValue(key) == null)
                    {
                        string path = folder + key;
                        if (!File.Exists(path))
                        {
                            kvs.Add(values[i]);
                        }
                    }
                }
            }
        }
    }
    /// <summary>
    /// 替换最新的资源记录
    /// </summary>
    public static void ReplaceAssetsRecord()
    {
        var net = NetVersion.ini.FindOrCreateSection(sec_Assets);
        AssetsRecord.ini.RemoveSection(sec_Assets);
        AssetsRecord.ini.AddSection(net);
        AssetsRecord.Changed = true;
    }
    /// <summary>
    /// 保存记录
    /// </summary>
    public static void SaveRecord()
    {
        if (AssetsRecord != null)
            AssetsRecord.Save();
    }
    /// <summary>
    /// 当网络资源更新完毕后，将其版本号保存
    /// </summary>
    public static void SaveNetVersion()
    {
        if (NetVersion != null)
        {
            var pub = NetVersion.ini.FindSection(sec_Public);
            if (pub != null)
            {
                var dra = AssetsRecord.ini.FindOrCreateSection(sec_Public);
                dra.Values.Clear();
                dra.Values.AddRange(pub.Values);
                AssetsRecord.ForceSave();
            }
        }
    }
    public static string GetCurAssVersion()
    {
        string str = null;
        if (AssetsRecord != null)
            str = AssetsRecord.GetString(sec_Public, pub_AssetsVersion);
        string str1 = null;
        if (BuildInVersion != null)
            str1 = BuildInVersion.GetString(sec_Public, pub_AssetsVersion);
        if (CompareNumber(str, str1) > 0)
            return str;
        return str1;
    }
    public static string GetNetAssVersion()
    {
        if (NetVersion != null)
            return NetVersion.GetString(sec_Public, pub_AssetsVersion);
        return null;
    }
    public static string GetBuildInAssVersion()
    {
        if (BuildInVersion != null)
            return BuildInVersion.GetString(sec_Public, pub_AssetsVersion);
        return null;
    }
    public static string GetNetValue(string block,string key)
    {
        if (NetVersion == null)
            return null;
        var sec = NetVersion.ini.FindSection(block);
        if (sec == null)
            return null;
        return sec.GetValue(key);
    }
    public static string GetBuildInValue(string block, string key)
    {
        if (BuildInVersion == null)
            return null;
        var sec = BuildInVersion.ini.FindSection(block);
        if (sec == null)
            return null;
        return sec.GetValue(key);
    }
}
